package com.test.mq.config;

import com.test.mq.constant.MQConstant;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 *
 *  该 交换器 模式 不求会玩
 * 头信息交换器
 *  一般的消息队列服务有3个概念：发消息者、队列、收消息者。
 *  而 rabbitMq 在 发消息者 和 队列 之间加入了一个  交换器(Exchange)。
 *  发消息者 将消息 发送给 交换器(Exchange)， 交换器根据调度策略再把消息再给队列
 */
//@Configuration
public class HeadersExchangeConfig {

    /**
     * 交换机(Exchange) 用于转发消息,但是它不会做存储,如果没有 队列(Queue) bind 到 Exchange 的话，它会直接丢弃掉 Producer 发送过来的消息
     * 针对消费者配置交换机
     FanoutExchange:  将消息分发到所有的绑定队列，无 路由键(routingkey) 的概念
     HeadersExchange：通过添加属性key-value匹配
     DirectExchange(默认交换机): 按照 路由键(routingkey) 分发到指定队列。在绑定时设定一个 routing_key, 消息的routing_key 匹配时, 才会被交换器投送到绑定的队列中去.
     TopicExchange:多关键字匹配
     */
    @Bean
    public HeadersExchange headersExchange() {
        // 消息不持久
        return new HeadersExchange(MQConstant.HEADERS_EXCHANGE_KEY);
    }
/*======================         示例队列一             ===========================*/

    /**
     * 注册 rabbitMq故障消息 sms短信转发 队列
     * @return
     */
    @Bean
    public Queue registerHeadersQueue1() {
        return new Queue(MQConstant.HEADERS_MQ_QUEUE_1); //默认durable=true,让队列持久
    }

    /**
     * 将交换机和消息队列绑定    Headers 类型的Exchanges是不处理路由键的，而是根据发送的消息内容中的headers属性进行匹配
     * whereAll()  即 x-match = all   :  表示所有的键值对都匹配才能接受到消息
     * whereAny()  即 x-match = any  ： 表示只要有键值对匹配就能接受到消息
     * @return
     */
    @Bean
    public Binding BindingHeadersQueue1() {
        return BindingBuilder.bind(registerHeadersQueue1()).to(headersExchange()).whereAll(MQConstant.HEADERS_MQ_HEARS).match();
    }



/*======================         示例队列二            ===========================*/


    /**
     * 注册 rabbitMq故障消息 websocket转发 队列
     * @return
     */
    @Bean
    public Queue registerHeadersQueue2() {
        return new Queue(MQConstant.HEADERS_MQ_QUEUE_2); //默认durable=true,让队列持久
    }

    /**
     *
     * 将交换机和消息队列绑定   Headers 类型的Exchanges是不处理路由键的，而是根据发送的消息内容中的headers属性进行匹配
     * whereAll()  即 x-match = all   :  表示所有的键值对都匹配才能接受到消息  Headers = {"x-match":"all","xxx",xxx}
     * whereAny()  即 x-match = any  ： 表示只要有键值对匹配就能接受到消息     Headers = {"x-match":"any","xxx",xxx}
     *
     * @return
     */
    @Bean
    public Binding BindingHeadersQueue2() {
        Map<String,Object> headers = new HashMap<String,Object>();
        return BindingBuilder.bind(registerHeadersQueue2()).to(headersExchange()).whereAny(MQConstant.HEADERS_MQ_HEARS).match();
    }
}
